/*
 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package com.sun.corba.se.impl.ior;

import org.omg.CORBA.OctetSeqHolder;

import org.omg.CORBA_2_3.portable.OutputStream;
import org.omg.CORBA_2_3.portable.InputStream;

import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher;

import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
import com.sun.corba.se.spi.ior.ObjectId;
import com.sun.corba.se.spi.ior.ObjectAdapterId;

import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.orb.ORBVersion;
import com.sun.corba.se.spi.orb.ORBVersionFactory;

import com.sun.corba.se.spi.logging.CORBALogDomains;

import com.sun.corba.se.impl.orbutil.ORBConstants;

import com.sun.corba.se.impl.encoding.CDRInputStream;

import com.sun.corba.se.impl.logging.IORSystemException;

/**
 * @author Ken Cavanaugh
 */
public class WireObjectKeyTemplate implements ObjectKeyTemplate {

  private ORB orb;
  private IORSystemException wrapper;

  public boolean equals(Object obj) {
    if (obj == null) {
      return false;
    }

    return obj instanceof WireObjectKeyTemplate;
  }

  public int hashCode() {
    return 53; // All WireObjectKeyTemplates are the same, so they should
    // have the same hashCode.
  }

  private byte[] getId(InputStream is) {
    CDRInputStream cis = (CDRInputStream) is;
    int len = cis.getBufferLength();
    byte[] result = new byte[len];
    cis.read_octet_array(result, 0, len);
    return result;
  }

  public WireObjectKeyTemplate(ORB orb) {
    initORB(orb);
  }

  public WireObjectKeyTemplate(InputStream is, OctetSeqHolder osh) {
    osh.value = getId(is);
    initORB((ORB) (is.orb()));
  }

  private void initORB(ORB orb) {
    this.orb = orb;
    wrapper = IORSystemException.get(orb,
        CORBALogDomains.OA_IOR);
  }

  public void write(ObjectId id, OutputStream os) {
    byte[] key = id.getId();
    os.write_octet_array(key, 0, key.length);
  }

  public void write(OutputStream os) {
    // Does nothing
  }

  public int getSubcontractId() {
    return ORBConstants.DEFAULT_SCID;
  }

  /**
   * While it might make sense to throw an exception here, this causes
   * problems since we need to check whether unusual object references
   * are local or not.  It seems that the easiest way to handle this is
   * to return an invalid server id.
   */
  public int getServerId() {
    return -1;
  }

  public String getORBId() {
    throw wrapper.orbIdNotAvailable();
  }

  public ObjectAdapterId getObjectAdapterId() {
    throw wrapper.objectAdapterIdNotAvailable();
  }

  /**
   * Adapter ID is not available, since our
   * ORB did not implement the object carrying this key.
   */
  public byte[] getAdapterId() {
    throw wrapper.adapterIdNotAvailable();
  }

  public ORBVersion getORBVersion() {
    return ORBVersionFactory.getFOREIGN();
  }

  public CorbaServerRequestDispatcher getServerRequestDispatcher(ORB orb, ObjectId id) {
    byte[] bid = id.getId();
    String str = new String(bid);
    return orb.getRequestDispatcherRegistry().getServerRequestDispatcher(str);
  }
}
